<?php
class Afiliados extends MY_Controller {

	// Datos para pasar a las vistas
	var $pageTitle = 'Prevet :: Afiliados';
	var $nombre_entidad = 'Afiliado';		// Cadena utilizada para los títulos de las páginas

	// Vistas manejadas por el controlador
	var $CARPETA_VISTAS = 'afiliados/';
	var $CARPETA_VISTAS_PRESTADOR = 'prestador/';
	
	var $pagina_editar;
	var $pagina_ver;
	var $pagina_ver_todos;
	var $pagina_reporte;

	public function __construct()
    {
    	parent::__construct();

		$this->pagina_ver_todos .= $this->CARPETA_VISTAS;
    	$this->pagina_ver .= $this->CARPETA_VISTAS;
    	$this->pagina_editar .= $this->CARPETA_VISTAS;
    	$this->pagina_reporte .= 'reportes/';
    	
    	if($this->template->usuarioActualEsPrestador())
    	{
			$this->pagina_ver_todos .= $this->CARPETA_VISTAS_PRESTADOR;
	    	$this->pagina_ver .= $this->CARPETA_VISTAS_PRESTADOR;
    	}
    	
    	$this->pagina_ver_todos .= 'afiliado_ver_todos_view';
    	$this->pagina_ver .= 'afiliado_ver_view';
    	$this->pagina_editar .= 'afiliado_edit_view';
    	$this->pagina_reporte .= 'afiliado_report_view';
	}

	/* Método que inicializa y busca la información básica necesaria para la definición de un nuevo elemento. */
	public function nuevo($id_duenio = 0, $id_mascota = 0)
	{
		$dataView['title'] = 'Agregar ' . $this->nombre_entidad; # Título de la página
		$dataView['id_elemento'] = NULL; 	// IMPORTANTE: debe ser nulo para un elemento nuevo

		# Creo un nuevo objeto de la entidad requerida y si se hubiesen enviado los identificadores como parámetros,
		# los cargo en el nuevo objeto creado.
		$obj_afiliado = new Afiliado();
		if($id_duenio != 0) $obj_afiliado->duenio_id = $id_duenio;
		if($id_mascota != 0)$obj_afiliado->animal_id = $id_mascota;
		$dataView['obj'.$this->nombre_entidad] = $obj_afiliado;

		$this->_cargarFormEdicion($dataView);
	}

	/* Método privado que se encarga de cargar en memoria los OBJETOS necesarios para el formulario de edición, 
	y mostrar este formulario con dicha información. */
	private function _cargarFormEdicion($dataView, $id_duenio = 0, $id_mascota = 0)
	{
		if(!isset($dataView['obj'.$this->nombre_entidad]))
		{
			$id_elemento = $dataView['id_elemento'];

			// Creo un objeto del modelo, para poblarlo con los datos que necesito mostrar
			$obj_afiliado = new Afiliado($id_elemento);
			$dataView['obj'.$this->nombre_entidad] = $obj_afiliado;
		}
		else $obj_afiliado = $dataView['obj'.$this->nombre_entidad];

		// Creo un objeto del modelo, para poder buscar todos los datos en la BD
		$obj_duenio = new Duenio();
		if($obj_afiliado->duenio_id != 0) {
			$obj_duenio->where('id', $obj_afiliado->duenio_id);
			$dataView['obj_duenio'] = $obj_duenio->get();
		}

		$obj_animal = new Animal();
		if($obj_afiliado->animal_id != 0) {
			$obj_animal->where('id', $obj_afiliado->animal_id);
			$dataView['obj_mascota'] = $obj_animal->get();
		}

		// Listado de razas para mostrar en los filtros
		$obj_raza = new Raza();
		$dataView['listado_razas'] = $obj_raza->get_iterated();

		$obj_pelaje = new Pelaje();
		$dataView['listado_pelajes'] = $obj_pelaje->get_iterated();

		$obj_contextura = new Contextura();
		$dataView['listado_contexturas'] = $obj_contextura->get_iterated();

		$obj_prestador = new Prestador();
		$dataView['listado_prestadores'] = $obj_prestador->get_iterated();

		// Filtrar planes disponibles según los datos de la mascota
		parent::_loadViews($this->pagina_editar, $dataView);
	}

	public function guardar()
	{
		$dataView['title'] = 'Guardar ' . $this->nombre_entidad;
		$dataView['error'] = '';

		// Se obtienen los datos del formulario para poblar el modelo
		$id_afiliado = is_numeric($this->input->post('txt_id')) ? $this->input->post('txt_id') : NULL;
		$obj_afiliado = new Afiliado($id_afiliado);

		$fecha_actual = date('d-m-Y');
		if($id_afiliado == 0 || $id_afiliado == NULL) {
			$obj_afiliado->fecha_afiliacion = $fecha_actual;
			$obj_afiliado->de_baja = FALSE;

			$obj_afiliado->fecha_creacion = date('Y-m-d H:i:s');
		}
		else $obj_afiliado->fecha_modificacion = date('Y-m-d H:i:s');

		// Defino el objeto que se desea asociar
		$id_animal = is_numeric($this->input->post('txt_animal')) ? $this->input->post('txt_animal') : NULL;
		$id_duenio = is_numeric($this->input->post('txt_duenio')) ? $this->input->post('txt_duenio') : NULL;

		$error_guardar = $this->_guardarPermitido($id_animal, $id_duenio, $id_afiliado);
		if($error_guardar == '')
		{
			$obj_animal = new Animal($id_animal);
			$obj_duenio = new Duenio($id_duenio);

			// Se manejan transacciones para interactuar con la BD
			$obj_afiliado->trans_begin();
			$operacion_exitosa = $obj_afiliado->save(array($obj_duenio, $obj_animal));
			if(!$operacion_exitosa && !$obj_afiliado->valid) // Falló la validación de datos
			{
				// Vuelvo a cargar el formulario de edición y mostrar los errores de validación
				$dataView['obj'.$this->nombre_entidad] = $obj_afiliado;
				$dataView['error'] = $obj_afiliado->error->string;
				$this->_cargarFormEdicion($dataView);
			}
			else
			{
				if ($obj_afiliado->trans_status() === FALSE) // Se chequea el estado de la transacción
				{
				    $obj_afiliado->trans_rollback(); // Si la transacción falló, hago un rollback
				}
				else
				{
				    $obj_afiliado->trans_commit(); // Transacción exitosa, realizo el commit
				}

				$dataView['error'] = $obj_afiliado->error->string; // Almaceno todos los errores que hubieran podido ocurrir
				$this->ver_todos($dataView);
			}
		}
		else
		{
			// Vuelvo a cargar el formulario de edición y mostrar los errores de validación
			$obj_afiliado->duenio_id = $id_duenio;
			$obj_afiliado->animal_id = $id_animal;
			$dataView['obj'.$this->nombre_entidad] = $obj_afiliado;
			$dataView['error'] = $error_guardar;
			$this->_cargarFormEdicion($dataView);
		}		
	}

	private function _mascotaConAfiliadoActivo($id_animal, $id_duenio, $id_afiliado)
	{
		$obj_afiliado = new Afiliado();
		$obj_afiliado->where('animal_id', $id_animal);
		$obj_afiliado->where('duenio_id !=', $id_duenio);
		$obj_afiliado->where('de_baja', FALSE);

		if($obj_afiliado->count() > 0) return TRUE;
		else return FALSE;
	}	

	private function _guardarPermitido($id_animal, $id_duenio, $id_afiliado)
	{
		if($id_animal == 0 || $id_animal == NULL || 
			$id_duenio == 0 || $id_duenio == NULL)
		{
			return 'Debe seleccionarse tanto el Dueño como la Mascota antes de continuar';
		}
		else {
			$obj_afiliado = new Afiliado();
			$obj_afiliado->where('animal_id', $id_animal);
			$obj_afiliado->where('duenio_id', $id_duenio);
			$obj_afiliado->where('id !=', $id_afiliado);

			if($obj_afiliado->count() > 0) {
				return "Ya existe un afiliado con el mismo dueño y mascota.";
			}
			else { // Si no está duplicado, controlo que la mascota no esté asociada a otro afiliado activo
				if($this->_mascotaConAfiliadoActivo($id_animal, $id_duenio, $id_afiliado)) {
					return "Ya existe un afiliado ACTIVO asociado a la mascota elegida.";
				}
				else return '';
			}
		}
	}

	
	public function ver_todos($dataView = array())
	{
		$dataView['title'] = 'Listado de ' . $this->nombre_entidad . 's';

		// Listado de razas para mostrar en los filtros
		$obj_raza = new Raza();
		$dataView['listado_razas'] = $obj_raza->get_iterated();

		// Listado de afiliados según filtros
		$dataView['listado'] = $this->_aplicarFiltros();

		parent::_loadViews($this->pagina_ver_todos, $dataView);
	}	

	private function _aplicarFiltros()
	{
		$existe_filtro = FALSE;

		// Listado de afiliados
		$obj_afiliado = new Afiliado();

		$num_afiliado = is_numeric($this->input->post('filtro_id_afiliado')) ? $this->input->post('filtro_id_afiliado') : NULL;
		if($num_afiliado != NULL) { $obj_afiliado->where('id', $num_afiliado); $existe_filtro = TRUE; }

		$nombre_mascota = trim($this->input->post('filtro_nombre_mascota'));
		if($nombre_mascota != '') { $obj_afiliado->ilike_related_animal('nombre', $nombre_mascota); $existe_filtro = TRUE; }

		$id_raza = is_numeric($this->input->post('filtro_raza')) ? $this->input->post('filtro_raza') : NULL;
		if($id_raza != 0) { $obj_afiliado->where_related_animal('raza_id', $id_raza); $existe_filtro = TRUE; }

		$nombre_duenio = trim($this->input->post('filtro_duenio'));
		if($nombre_duenio != '') { $obj_afiliado->ilike_related_duenio('apellido', $nombre_duenio); $existe_filtro = TRUE; }

		$dni_duenio = is_numeric($this->input->post('filtro_dni_duenio')) ? $this->input->post('filtro_dni_duenio') : NULL;
		if($dni_duenio != NULL) { $obj_afiliado->where_related_duenio('dni', $dni_duenio); $existe_filtro = TRUE; }

		$fecha_desde = $this->input->post('filtro_ingreso_desde');
		if($fecha_desde != '') { $obj_afiliado->where('fecha_afiliacion >=', $this->util_fechas->prepararFecha($fecha_desde)); $existe_filtro = TRUE; }

		$fecha_hasta = $this->input->post('filtro_ingreso_hasta');
		if($fecha_hasta != '') { $obj_afiliado->where('fecha_afiliacion <=', $this->util_fechas->prepararFecha($fecha_hasta)); $existe_filtro = TRUE; }

		$estado = is_numeric($this->input->post('filtro_estado')) ? $this->input->post('filtro_estado') : NULL;
		if($estado != 2 && $estado != NULL) { $obj_afiliado->where('de_baja', $estado); $existe_filtro = TRUE; }

		// Si no se hubieran realizado filtros, se muestran los 10 primeros
		if(!$existe_filtro) {
			$obj_afiliado->limit(10);
			$obj_afiliado->order_by("id", "desc");
		}

		return $obj_afiliado->get_iterated();
	}

	public function ver($id_elemento)
	{
		$dataView['title'] = 'Ver ' . $this->nombre_entidad . ': ' . $id_elemento;

		// Creo un objeto del modelo, para poblarlo con los datos que necesito mostrar
		$obj_afiliado = new Afiliado($id_elemento);
		$dataView['obj'.$this->nombre_entidad] = $obj_afiliado;

		$dataView['listado_historial'] = $obj_afiliado->historial_plan->get();

		$esPrestador = $this->template->usuarioActualEsPrestador();
		$dataView['usuario_esPrestador'] = $esPrestador;

		$this->load->library('util_historial_plan');
		$idHistPlanActual = $this->util_historial_plan->getIdHistorialPlanActual($id_elemento);
		$dataView['idHistPlanActual'] = $idHistPlanActual;

		parent::_loadViews($this->pagina_ver, $dataView);
	}

	public function establecer_estado($id_elemento)
	{
		$dataView['title'] = 'Cambiar estado de ' . $this->nombre_entidad;
		$dataView['error'] = '';

		if($this->validarEliminacion($id_elemento))
		{
			$continuar = TRUE;

			// Se obtiene el objeto que se desea eliminar
			$obj_afiliado = new Afiliado($id_elemento);

			if(!$obj_afiliado->de_baja) {
				$obj_afiliado->de_baja = TRUE;
				$obj_afiliado->fecha_baja = date('d/m/Y');
			}
			else {
				/* Si hay que activar al AFILIADO, lo hago únicamente si la mascota no está ya asociada ahora a 
				otro afiliado activo. */
				if(!$this->_mascotaConAfiliadoActivo($obj_afiliado->animal_id, $obj_afiliado->duenio_id, $obj_afiliado->id))
					{ $obj_afiliado->de_baja = FALSE; }
				else $continuar = FALSE;
			}

			if($continuar) {
				// Se manejan transacciones para interactuar con la BD
				$obj_afiliado->trans_begin();
				$obj_afiliado->save();
				if ($obj_afiliado->trans_status() === FALSE) // Se chequea el estado de la transacción
				{
				    $obj_afiliado->trans_rollback(); // Si la transacción falló, hago un rollback
				}
				else
				{
				    $obj_afiliado->trans_commit(); // Transacción exitosa, realizo el commit
				}

				$dataView['error'] = $obj_afiliado->error->string; // Almaceno todos los errores que hubieran podido ocurrir
			}
			else $dataView['error'] = "No se puede Activar el afiliado ya que la mascota está actualmente asociada a otro afiliado ACTIVO.";

			$this->ver_todos($dataView);
		}
		else
		{
			$dataView['error'] = 'No se puede dar de baja el afiliado elegido.';
			$dataView['path_volver'] = 'afiliados/ver_todos';
			parent::_loadViews($this->template->getErrorMessageView(), $dataView);
		}
	}

	/* IMPORTANTE: este método es llamado desde la función heredada de MY_Controller, "borradoPosible" */
	protected function validarEliminacion($id_elemento)
	{
		return TRUE;
	}

	public function informe($dataView = array())
	{
		$dataView['title'] = 'Generar informe de ' . $this->nombre_entidad . 's';
		parent::_loadViews($this->pagina_reporte, $dataView);
	}

	public function generar_reporte()
	{	
		$dataView['title'] = 'Generar informe de ' . $this->nombre_entidad . 's';
		$titulo = 'Listado de ' . $this->nombre_entidad . 's';
		$dataView['titulo'] = $titulo;

		// Obtengo el listado de Afiliados a mostrar
		$listado = $this->_aplicarFiltros();
		if($listado->exists()) {

			$this->load->library('to_excel');
			$objPHPExcel = $this->to_excel->getExcelObject($titulo);
			
			// Defino estilos de los títulos
			$objPHPExcel->getActiveSheet()->getStyle('A3:H3')->applyFromArray($this->to_excel->getHeadersStyle());

			$objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', $titulo);
			$objPHPExcel->setActiveSheetIndex(0)->setCellValue('G1', date('d/m/Y h:m'));
			$objPHPExcel->getActiveSheet()->mergeCells('A1:F1'); // Título
			$objPHPExcel->getActiveSheet()->mergeCells('G1:H1'); // Fecha de obtención del reporte
			$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->applyFromArray($this->to_excel->getTitleStyle());

			// Arranco de la fila 3 ya que dejo una en blanco
			$fila_inicio = 3;
			$objPHPExcel->setActiveSheetIndex(0)->setCellValue('A'.$fila_inicio, 'N°');
			$objPHPExcel->setActiveSheetIndex(0)->setCellValue('B'.$fila_inicio, 'Afiliación');
			$objPHPExcel->setActiveSheetIndex(0)->setCellValue('C'.$fila_inicio, 'Dueño');
			$objPHPExcel->setActiveSheetIndex(0)->setCellValue('D'.$fila_inicio, 'Domicilio');
			$objPHPExcel->setActiveSheetIndex(0)->setCellValue('E'.$fila_inicio, 'Teléfono');
			$objPHPExcel->setActiveSheetIndex(0)->setCellValue('F'.$fila_inicio, 'Mascota');
			$objPHPExcel->setActiveSheetIndex(0)->setCellValue('G'.$fila_inicio, 'Raza');
			$objPHPExcel->setActiveSheetIndex(0)->setCellValue('H'.$fila_inicio, 'Estado');

			$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setAutoSize(true);
			$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);
			$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true);
			$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setAutoSize(true);
			$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setAutoSize(true);
			$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setAutoSize(true);
			$objPHPExcel->getActiveSheet()->getColumnDimension('G')->setAutoSize(true);
			$objPHPExcel->getActiveSheet()->getColumnDimension('H')->setAutoSize(true);

			// Renombrar Hoja
			$objPHPExcel->getActiveSheet()->setTitle('Afiliados');

			// Establecer la hoja activa, para que cuando se abra el documento se muestre primero.
			$objPHPExcel->setActiveSheetIndex(0);

			$fila = $fila_inicio;
			foreach ($listado as $afiliado) {
				$fila++;

				$afiliado->duenio->get();
				$afiliado->animal->get();
				$afiliado->animal->raza->get();
				$objPHPExcel->setActiveSheetIndex(0)->setCellValue('A'.$fila, $afiliado->id);
				$objPHPExcel->setActiveSheetIndex(0)->setCellValue('B'.$fila, $afiliado->fecha_afiliacion);
				$objPHPExcel->setActiveSheetIndex(0)->setCellValue('C'.$fila, $afiliado->duenio->apellido . ', ' . $afiliado->duenio->nombre);
				$objPHPExcel->setActiveSheetIndex(0)->setCellValue('D'.$fila, $afiliado->duenio->domicilio);
				$objPHPExcel->setActiveSheetIndex(0)->setCellValue('E'.$fila, $afiliado->duenio->telefono);
				$objPHPExcel->setActiveSheetIndex(0)->setCellValue('F'.$fila, $afiliado->animal->nombre);
				$objPHPExcel->setActiveSheetIndex(0)->setCellValue('G'.$fila, $afiliado->animal->raza->nombre);

				$estado = $afiliado->de_baja ? 'Inactivo' : 'Activo';
				if($afiliado->de_baja) $estado .= " ($afiliado->fecha_baja)";
				$objPHPExcel->setActiveSheetIndex(0)->setCellValue('H'.$fila, $estado);
			}

			$dataView['objWriter'] = $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
			$dataView['objPHPExcel'] = $objPHPExcel;

			$this->load->view('reportes/report_view', $dataView);
		}
		else { 
			$dataView['error'] = 'La consulta no produjo resultados.';
			$this->informe($dataView);
		}
	}
}